<?php
/**
 * Created by PhpStorm.
 * User: wangjie
 * Date: 2020/07/27
 * Time: 下午5:13
 */

namespace App\Api\Controllers\LeshuaUnion;

use App\Api\Controllers\BaseController;
use App\Api\Controllers\Config\LeshuaUnionPayConfigController;
use App\Common\PaySuccessAction;
use App\Common\RefundSuccessAction;
use App\Exceptions\BizException;
use App\Models\MerchantWalletDetail;
use App\Models\Order;
use App\Models\RefundOrder;
use App\Models\RefundOrderDoing;
use App\Models\UserWalletDetail;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Schema;
use App\Api\Controllers\Cmbc\BaseController as base;

class NotifyController extends BaseController
{

    protected function xml_to_array($xml)
    {
        if (!$xml) {
            die("xml数据异常！");
        }

        libxml_disable_entity_loader(true); //禁止引用外部xml实体
        $values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);

        return $values;
    }


    public function pay_notify_url(Request $request): string
    {
        try {
            $ackCode = "000000";
            $xml = $request->getContent();
            Log::channel("leshuaunion")->info("pay_notify_url_content", [$xml]);
            $data = $this->xml_to_array($xml);
            Log::channel("leshuaunion")->info("pay_notify_url", $data);
            $out_trade_no = $data["third_order_id"];
            $order_status = $data["status"];
            $day = date('Ymd', time());
            $table = 'orders_' . $day;
            if (Schema::hasTable($table)) {
                $order = DB::table($table)->where('out_trade_no', $out_trade_no)->first();
            } else {
                $order = Order::where('out_trade_no', $out_trade_no)->first();
            }
            if (empty($order)) {
                throw new BizException("支付订单不存在");
            } else if ($order->pay_status == 1) {
                return $ackCode;
            }

            $config = new LeshuaUnionPayConfigController();
            $config = $config->config($order->config_id);
            if (empty($config)) {
                throw new BizException("乐刷配置不存在");
            }
            $base = \App\Api\Controllers\LeshuaUnion\BaseController::getInstance();
            $error_code = $data["error_code"];
            unset($data["error_code"]);
            $verify = $base->verify($data, $config->verify_key, false);
            if (empty($verify)) {
                throw new BizException("验证失败");
            }

//            $mch_id = $data["merchant_id"] ?? "";

            switch ($order_status) {
                case 2:
                    if ($order->ways_source == 'weixin' && isset($data['promotion_detail'])) {
                        \App\Common\PaySuccessAction::addCoupon($order->out_trade_no, $data['promotion_detail'], 'pay');
                    }
                    $in_data = [
                        'status' => '1',
                        'pay_status' => 1,
                        'pay_status_desc' => '支付成功',
                        'trade_no' => $data["out_transaction_id"] ?? "",
                        'pay_time' => $data["pay_time"] ?? date("Y-m-d H:i:s", time()),
                        'buyer_id' => $data["sub_openid"] ?? "",
                        'buyer_pay_amount' => bcdiv((string)$data["buyer_pay_amount"], "100", 2) ?? $data["amount"],
                    ];
                    $this->update_day_order($in_data, $out_trade_no);
                    if (strpos($out_trade_no, 'scan')) {

                    } else {
                        //支付成功后的动作
                        $data = [
                            'ways_type' => $order->ways_type,
                            'company' => $order->company,
                            'ways_type_desc' => $order->ways_type_desc,
                            'source_type' => '140001', //返佣来源
                            'source_desc' => '乐刷联合收单', //返佣来源说明
                            'total_amount' => $order->total_amount,
                            'out_trade_no' => $order->out_trade_no,
                            'other_no' => $order->other_no,
                            'rate' => $order->rate,
                            'fee_amount' => $order->fee_amount,
                            'merchant_id' => $order->merchant_id,
                            'store_id' => $order->store_id,
                            'user_id' => $order->user_id,
                            'config_id' => $order->config_id,
                            'store_name' => $order->store_name,
                            'ways_source' => $order->ways_source,
                            'pay_time' => $in_data["pay_time"],
                            'device_id' => $order->device_id,
                        ];
                        PaySuccessAction::action($data);
                    }
                    Log::channel("leshuaunion")->info("pay_notify_success", [$xml]);
                    break;
                case 3:
                    $ackCode = "";
                    break;

            }
            return $ackCode;
        } catch (\Exception $ex) {
            Log::channel("leshuaunion")->info("pay_notify_error", [$ex->getMessage() . $ex->getLine()]);
            return $ex->getMessage() . $ex->getLine();
        }
    }


    public function refund_notify_url(Request $request): string
    {
        try {
            $ackCode = "000000";
            $xml = $request->getContent();
            Log::channel("leshuaunion")->info("refund_notify_url_xml", [$xml]);
            $data = $this->xml_to_array($xml);
            Log::channel("leshuaunion")->info("refund_notify_url_data", $data);
            $out_trade_no = $data["third_order_id"];
            $order_status = $data["status"];
            $day = date('Ymd', time());
            $table = 'orders_' . $day;
            sleep(3);
            if (Schema::hasTable($table)) {
                $order = DB::table($table)->where('out_trade_no', $out_trade_no)->first();
            } else {
                $order = Order::where('out_trade_no', $out_trade_no)->first();
            }
            if (empty($order)) {
                throw new BizException("支付订单不存在");
            } else if ($order->pay_status == 6) {
                return $ackCode;
            }
            $attach = json_decode($data["attach"], true);
            Log::channel("leshuaunion")->info("refund_notify_url_attach", [
                $attach
            ]);
            $config = new LeshuaUnionPayConfigController();
            $config = $config->config($order->config_id);
            if (empty($config)) {
                throw new BizException("乐刷配置不存在");
            }
            $base = \App\Api\Controllers\LeshuaUnion\BaseController::getInstance();
            $error_code = $data["error_code"];
            unset($data["error_code"]);
            $verify = $base->verify($data, $config->verify_key, false);
            if (empty($verify)) {
                throw new BizException("验证失败");
            }
            if ($data["status"] == 11) {
                $insert_data = [
                    'status' => '6',
                    'pay_status' => 6,
                    'pay_status_desc' => '已退款',
                    'refund_amount' => $attach['new_refund_amount'] ?? 0,
                    'fee_amount' => $attach['new_fee_amount'] ?? 0
                ];
                (new \App\Api\Controllers\BaseController())->update_day_order($insert_data, $order->out_trade_no);
                RefundOrderDoing::query()->where("other_refund_no", $data["leshua_refund_id"])->update(["status" => 2]);
                RefundOrder::create([
                    'ways_source' => $order->ways_source,
                    'type' => $order->ways_type,
                    'refund_amount' => bcdiv((string)$data['refund_amount'], "100", 2), //退款金额
                    'refund_no' => $data['merchant_refund_id'], //平台退款单号
                    "other_refund_no" => $data["leshua_refund_id"],
                    'store_id' => $order->store_id,
                    'merchant_id' => $order->merchant_id,
                    'out_trade_no' => $order->out_trade_no,
                    'trade_no' => $order->trade_no
                ]);
                if (isset($data['refund_detail']) && !empty($data['refund_detail'])) {
                    \App\Common\PaySuccessAction::addCoupon($order->out_trade_no, $data['refund_detail'], 'refund');
                }
                //退款成功后的操作
                RefundSuccessAction::action([
                    'out_trade_no' => $order->out_trade_no,
                    'refund_no' => $data['merchant_refund_id'], //平台退款单号
                ]);
                //返佣去掉
                UserWalletDetail::where('out_trade_no', $order->out_trade_no)->update([
                    'settlement' => '03',
                    'settlement_desc' => '退款订单'
                ]);
                MerchantWalletDetail::where('out_trade_no', $order->out_trade_no)->update([
                    'settlement' => '03',
                    'settlement_desc' => '退款订单'
                ]);
                Log::channel("leshuaunion")->info("refund_notify_success", [
                    'ways_source' => $order->ways_source,
                    'type' => $order->ways_type,
                    'refund_amount' => bcsub((string)$data['refund_amount'], "100", 2), //退款金额
                    'refund_no' => $data['merchant_refund_id'], //平台退款单号
                    "other_refund_no" => $data["leshua_refund_id"],
                    'store_id' => $order->store_id,
                    'merchant_id' => $order->merchant_id,
                    'out_trade_no' => $order->out_trade_no,
                    'trade_no' => $order->trade_no
                ]);
                return $ackCode;
            } else if ($data["status"] == 10) {
                $insert_data = [
                    'status' => '5',
                    'pay_status' => 5,
                    'pay_status_desc' => '退款中'
                ];
                $res = (new \App\Api\Controllers\BaseController())->update_day_order($insert_data, $order->out_trade_no);
                if (!$res) {
                    Log::info('乐刷-退款中-更新失败');
                }
                return "退款中";
            } else {

                return "退款失败";
            }
        } catch (\Exception $e) {
            Log::channel("leshuaunion")->info("refund_notify_exception", [
                "error" => $e->getMessage(),
                "line" => $e->getLine(),
                "file" => $e->getFile()
            ]);
            return $e->getMessage();
        }
    }


    public function embedPayNotify(Request $request): string
    {
        try {
            $data = $request->post();
            Log::channel("leshuaunion")->info("embedPayNotify_arr", $data);
            $order = Order::query()->where("out_trade_no", $data["third_order"])->first();
            if (empty($order)) {
                throw new BizException("订单不存在");
            }
            if (in_array($order->pay_status, [1, 6])) {
                throw new BizException("订单已支付");
            }
            $config = new LeshuaUnionPayConfigController();
            $config = $config->config($order->config_id);
            if (empty($config)) {
                throw new BizException("乐刷配置不存在");
            }
            $base = \App\Api\Controllers\LeshuaUnion\BaseController::getInstance();
            unset($data["error_code"]);
            if (isset($data["sign"])) {
                $verify = $base->verify($data, $config->verify_key, false);
                if (empty($verify)) {
                    throw new BizException("验证失败");
                }
            }
            $status = $data["status"];
            if ($status == 2) {
                if ($order->ways_source == 'weixin' && isset($data['promotion_detail'])) {
                    \App\Common\PaySuccessAction::addCoupon($order->out_trade_no, $data['promotion_detail'], 'pay');
                }
                $in_data = [
                    'status' => '1',
                    'pay_status' => 1,
                    'pay_status_desc' => '支付成功',
                    'trade_no' => $data["out_transaction_id"] ?? "",
                    'pay_time' => $data["pay_time"] ?? date("Y-m-d H:i:s", time()),
                    'buyer_id' => $data["sub_openid"] ?? "",
                    'buyer_pay_amount' => bcdiv((string)$data["buyer_pay_amount"], "100", 2) ?? $data["amount"],
                ];
                $this->update_day_order($in_data, $order->out_trade_no);
                if (strpos($order->out_trade_no, 'scan')) {

                } else {
                    //支付成功后的动作
                    $data = [
                        'ways_type' => $order->ways_type,
                        'company' => $order->company,
                        'ways_type_desc' => $order->ways_type_desc,
                        'source_type' => '140001', //返佣来源
                        'source_desc' => '乐刷联合收单', //返佣来源说明
                        'total_amount' => $order->total_amount,
                        'out_trade_no' => $order->out_trade_no,
                        'other_no' => $order->other_no,
                        'rate' => $order->rate,
                        'fee_amount' => $order->fee_amount,
                        'merchant_id' => $order->merchant_id,
                        'store_id' => $order->store_id,
                        'user_id' => $order->user_id,
                        'config_id' => $order->config_id,
                        'store_name' => $order->store_name,
                        'ways_source' => $order->ways_source,
                        'pay_time' => $in_data["pay_time"],
                        'device_id' => $order->device_id,
                    ];
                    PaySuccessAction::action($data);
                }
                Log::channel("leshuaunion")->info("pay_notify_success", [$data]);
                return "000000";
            }
            return "";
        } catch (\Exception $e) {
            Log::channel("leshuaunion")->info("pay_notify_error", [
                $e->getMessage() . $e->getFile() . $e->getLine()
            ]);
            return $e->getMessage() . $e->getFile() . $e->getLine();
        }
    }

}
